Skip to content

fix(providers): honour config.yaml api_key for anthropic provider - #7581

Open
FrankSen wants to merge 1 commit into
NousResearch:mainfrom
FrankSen:fix/anthropic-config-api-key
Open

FrankSen wants to merge 1 commit into
NousResearch:mainfrom
FrankSen:fix/anthropic-config-api-key

Conversation

@FrankSen

Copy link
Copy Markdown

Summary

Fixes #7579

  • Add model.api_key / model.api from config.yaml as a candidate source for the anthropic provider, consistent with how all other providers (openrouter, custom, minimax, etc.) handle it
  • Apply the fix in both the main resolution path (resolve_runtime_provider) and the explicit override path (_resolve_explicit_runtime)
  • Add 2 new tests verifying config api_key and api field resolution

Priority order after fix

  1. Explicit API key (CLI --api-key flag)
  2. config.yaml model.api_key / model.api
  3. ANTHROPIC_TOKEN env var
  4. CLAUDE_CODE_OAUTH_TOKEN env var
  5. Claude Code credential files
  6. ANTHROPIC_API_KEY env var

Test plan

  • All 62 existing + new tests pass (pytest tests/hermes_cli/test_runtime_provider_resolution.py)
  • Manually verified: hermes chat works with only config.yaml api_key set (no env vars)
  • Existing anthropic env var resolution still works when config api_key is absent

The anthropic provider code path in `resolve_runtime_provider()` only
checked env vars (ANTHROPIC_TOKEN, ANTHROPIC_API_KEY) and credential
files for API key resolution, completely ignoring `model.api_key` from
config.yaml. This is inconsistent with all other providers (openrouter,
custom, minimax, etc.) which read config.yaml api_key as a candidate.

Users who configure `provider: anthropic` with `api_key` in config.yaml
(e.g. pointing to a self-hosted proxy) were forced to duplicate the key
in env vars, which is confusing and unnecessary.

This change adds config.yaml `model.api_key` (and `model.api` alias) as
a candidate source in both the main anthropic resolution path and the
explicit override path, consistent with how other providers handle it.

Priority order is now:
  1. Explicit API key (CLI flag)
  2. config.yaml model.api_key / model.api
  3. ANTHROPIC_TOKEN env var
  4. CLAUDE_CODE_OAUTH_TOKEN env var
  5. Claude Code credential files
  6. ANTHROPIC_API_KEY env var

Co-Authored-By: Franksen <youngsenman@163.com>
@FrankSen

Copy link
Copy Markdown
Author

Friendly ping — any feedback on this fix? Happy to adjust if needed.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard provider/anthropic Anthropic native Messages API area/config Config system, migrations, profiles labels Apr 29, 2026
@alt-glitch

Copy link
Copy Markdown

Related to #9105 (same root cause: anthropic provider path in resolve_runtime_provider() skips config.yaml api_key). Also related to closed #11713.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for identifying the missing Anthropic configuration path. The underlying non-Azure gap still exists on current main: hermes_cli/runtime_provider.py:1901-1908 calls resolve_anthropic_token() without considering model.api_key.

Problems

  • The resolver was substantially refactored after this PR. The current explicit path is hermes_cli/runtime_provider.py:1367-1392 and the normal native path is :1849-1916, so this patch needs a focused port rather than a direct cherry-pick.
  • The new tests cover only the normal resolver. They do not exercise the explicit branch changed by the PR, which is entered only with an explicit runtime argument (hermes_cli/runtime_provider.py:1362-1365, :1658-1666).
  • Current configuration/docs define model.api_key as custom-endpoint-only (hermes_cli/config.py:4555-4559; website/docs/user-guide/features/credential-pools.md:188). Extending it to native Anthropic needs that contract reconciled.

Suggested changes

  • Port both branches and add one explicit-base-url regression with only model.api_key configured.
  • Update the configuration/docs contract if native Anthropic inline keys are intentional.

Automated hermes-sweeper review.

assert resolved.get("credential_pool") is None


def test_resolve_runtime_provider_anthropic_respects_config_api_key(monkeypatch):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This covers the normal resolver only. Please add a regression for the _resolve_explicit_runtime path as well: pass explicit_base_url with no explicit_api_key, provide model.api_key, and assert it wins without calling resolve_anthropic_token.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit labels Jul 12, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists provider/anthropic Anthropic native Messages API sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anthropic provider ignores config.yaml api_key, requiring duplicate env var configuration

3 participants